package ru.compft.common.dao.impl;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import ru.compft.common.dao.ModuleDao;
import ru.compft.common.data.Module;
import ru.compft.common.data.ModulePage;
import ru.compft.common.data.meta.ModulePageProperty;
import ru.compft.common.data.meta.ModuleProperty;

import javax.annotation.Resource;
import java.util.List;

/**
 * User: VVasiliev
 * Date: 14.06.12
 * Time: 14:08
 * DAO работы с модулями
 */
@Repository
public class ModuleDaoImpl implements ModuleDao {
    private static final Logger logger = LoggerFactory.getLogger(ModuleDaoImpl.class);

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    @Override
    public List<Module> getAllModules() {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Module.class);

            return criteria.list();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public List<Module> getModules(int from, int count) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Module.class)
                    .setFirstResult(from)
                    .setMaxResults(count);

            return criteria.list();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public int countAllModules() {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Module.class)
                    .setProjection(Projections.rowCount());

            final Object result = criteria.uniqueResult();
            return result != null ? Integer.parseInt(result.toString()): 0;
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return 0;
    }

    @Override
    public Module getModuleById(Long moduleId) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            return (Module) session.get(Module.class, moduleId);
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public Module getModuleByCode(String code) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Module.class)
                    .add(Restrictions.like(ModuleProperty.code, code));

            return (Module) criteria.uniqueResult();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

//    @Override
//    public Module getModuleByPath(String path) {
//        Session session = null;
//        try {
//            session = sessionFactory.openSession();
//            Criteria criteria = session.createCriteria(Module.class)
//                    .add(Restrictions.like(ModuleProperty.path, path));
//
//            return (Module) criteria.uniqueResult();
//        } catch (HibernateException e) {
//            logger.error(e.getMessage(), e);
//        } finally {
//            if (session != null && session.isOpen()) session.close();
//        }
//        return null;
//    }

//    @Override
//    public Long generateId() {
//        return System.currentTimeMillis();
//    }

    @Override
    public Module update(Module module) {
        Session session = null;
        Module result = module;
        try {
            session = sessionFactory.openSession();
//            Transaction transaction = session.beginTransaction();
            result = (Module) session.merge(module);
//            transaction.commit();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return result;
    }

    @Override
    public List<ModulePage> getAllModulePages() {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(ModulePage.class);

            return criteria.list();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public List<ModulePage> getAllPagesToModule(Long moduleId) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(ModulePage.class)
                    .add(Restrictions.eq(ModulePageProperty.moduleId, moduleId));

            return criteria.list();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

//    @Override
//    public List<ModulePage> getAllPagesToModules() {
//        return readModulePagesFromFile();
//    }
}
